package com.server.common.code.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.server.model.all.constant.ProfileConstant;
import com.server.common.code.domain.VerifyCode;
import lombok.extern.slf4j.Slf4j;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import java.util.UUID;

@Slf4j
public class VerifyCodeUtils {
    private static final int w = 70;
    private static final int h = 35;
    private static final Random r = new Random();
    // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
    private static final String[] fontNames =
            { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" };
    // 可选字符
    private static final String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
    // 背景色
    private static final Color bgColor = new Color(255, 255, 255);

    // 生成随机的颜色
    private static Color randomColor() {
        int red = r.nextInt(150);
        int green = r.nextInt(150);
        int blue = r.nextInt(150);
        return new Color(red, green, blue);
    }

    // 生成随机的字体
    private static Font randomFont() {
        int index = r.nextInt(fontNames.length);
        String fontName = fontNames[index];// 生成随机的字体名称
        int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
        int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
        return new Font(fontName, style, size);
    }

    // 画干扰线
    private static void drawLine(BufferedImage image,Color color) {
        int num = 3;// 一共画3条
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        for (int i = 0; i < num; i++) {// 生成两个点的坐标，即4个值
            int x1 = RandomUtil.randomInt(w/2);
            int y1 = RandomUtil.randomInt(h);
            int x2 = RandomUtil.randomInt(w);
            int y2 = RandomUtil.randomInt(h);
            g2.setStroke(new BasicStroke(1.5F));
            g2.setColor(color);
            g2.drawLine(x1, y1, x2, y2);// 画线
        }
    }

    // 随机生成一个字符
    private static char randomChar() {
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }

    // 创建BufferedImage
    private static BufferedImage createImage() {
        BufferedImage image = new BufferedImage(w, h,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        g2.setColor(bgColor);
        g2.fillRect(0, 0, w, h);
        return image;
    }

    // ！调用这个方法得到验证码
    public static VerifyCode getImage() {
        VerifyCode verifyCode = new VerifyCode();
        BufferedImage image = createImage();// 创建图片缓冲区
        Graphics2D g2 = (Graphics2D) image.getGraphics();// 得到绘制环境
        StringBuilder sb = new StringBuilder();// 用来装载生成的验证码文本
        // 向图片中画4个字符
        for (int i = 0; i < 4; i++) {// 循环四次，每次生成一个字符
            Color color = randomColor();
            String s = randomChar() + "";// 随机生成一个字母
            sb.append(s); // 把字母添加到sb中
            float x = i * 1.0F * w / 4; // 设置当前字符的x轴坐标
            g2.setFont(randomFont()); // 设置随机字体
            g2.setColor(color); // 设置随机颜色
            g2.drawString(s, x, h - 5); // 画图
            drawLine(image,color); // 添加干扰线
        }
        verifyCode.setTextValue(sb.toString());

        try (ByteArrayOutputStream outStream = new ByteArrayOutputStream();){
            ImgUtil.write(image,"JPEG",outStream);
            verifyCode.setBase64Image(Base64.encode(outStream.toByteArray()));
        }catch (Exception e){
            log.error("写入失败",e);
        }
        verifyCode.setTextCode(UUID.randomUUID().toString().replace("-",""));

        //开发环境
        if(ProfileConstant.DEV.equals(SpringUtil.getActiveProfile())){
            verifyCode.setTextValue("1234");
        }

        return verifyCode;
    }

}
